﻿using A.M.ETO;
using A.M.Storage.Application;
using AutoMapper;
using DotNetCore.CAP;
using Hangfire;
using LinqKit;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using O.M.Production.Application.IService;
using O.M.Production.Domain.DTO;
using O.M.Production.Domain.Entity;
using O.M.Production.ErrorCodeEnum;
using O.M.Production.Infrastuecure.IRepository;
using Public_Class_Library;
using Q.M.Sell.Doamin.DTO;
using Q.M.Sell.Doamin.Entity;
using Redis_ClientInfor;
using SqlSugar;
using System.Collections.Generic;
using System.DirectoryServices.ActiveDirectory;
using System.Linq.Expressions;
using W.M.Materiel.Domain.Entity;
using W.M.Materiel.Infrastruecure.DTO;
using static O.M.Production.Domain.EnumModel;

namespace O.M.Production.Application.Service
{
    /// <summary>
    /// 内部生产服务实现类
    /// </summary>
    public class internal_product_Service : BaseServices<internal_product, string>, I_internal_product_Service
    {
        private readonly Cross_service_Helper cross_Service_Helper;
        private readonly I_internal_product_Repository _i_Internal_Product_Repository;
        private readonly I_produce_product_Repository _Produce_Product_Repository;
        private readonly I_produce_material_Repository _produce_material_Repository;
        private readonly IMapper _mapper;
        private readonly ICapPublisher capPublisher;
        private readonly Cross_service_Helper _cross_service_helper;
        public internal_product_Service(I_internal_product_Repository Internal_Product_Repository, IMapper mapper, I_produce_material_Repository produce_material_Repository, I_produce_product_Repository produce_Product_Repository, ICapPublisher capPublisher, Cross_service_Helper cross_service_helper, Cross_service_Helper cross_Service_Helper) : base(Internal_Product_Repository)
        {
            _i_Internal_Product_Repository = Internal_Product_Repository;
            _mapper = mapper;
            _produce_material_Repository = produce_material_Repository;
            _Produce_Product_Repository = produce_Product_Repository;
            this.capPublisher = capPublisher;
            _cross_service_helper = cross_service_helper;
            this.cross_Service_Helper = cross_Service_Helper;
        }

        /// <summary>
        /// 分页查询-内部生产
        /// </summary>
        /// <param name="IPName">模糊查询编号或者名称</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="pageIndex">页码</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiResult> Get_internal_product_Page(string? IPName, Produce_Type? produce_type, int pageSize, int pageIndex)
        {
            try
            {
                ApiResult apiResult = new ApiResult();
                await Get_Redis(IPName, produce_type, pageSize, pageIndex);
                var redisdb = RedisClient.redisClient.GetStringKey<ApiResult>("OyxKey");

                if (redisdb == null || redisdb.Data == "" || redisdb.Data == null)
                {
                    return await Get_Redis(IPName, produce_type, pageSize, pageIndex);
                }
                else
                {
                    //apiResult.totalCount = redisdb.Count();
                    //apiResult.pageCount = (int)Math.Ceiling(redisdb.Count() * 1.0 / pageSize);
                    //apiResult.Data = redisdb.OrderByDescending(x => x._add_time).ToList();
                    return redisdb;
                }
            }
            catch (Exception)
            {

                throw;
            }
        }
        private async Task<ApiResult> Get_Redis(string? IPName, Produce_Type? produce_type, int pageSize, int pageIndex)
        {
            try
            {
                ApiResult apiResult = new ApiResult();
                Expression<Func<internal_product, bool>> whereexp = i => true;
                if (!string.IsNullOrEmpty(IPName))
                {
                    Expression<Func<internal_product, bool>> IPNameWhere = i => i.produce_theme.Contains(IPName) || i.internal_product_id.Contains(IPName);
                    whereexp = whereexp.And(IPNameWhere);  // 组合条件  
                }
                if (produce_type > 0)
                {
                    Expression<Func<internal_product, bool>> produceTypeExpression = i => i.produce_type == produce_type.Value;
                    whereexp = whereexp.And(produceTypeExpression); // 组合条件  
                }
                //var list1 = await _i_Internal_Product_Repository.GetShowInforAsync();
                //RedisClient.redisClient.SetStringKey("OyxKey", list1, TimeSpan.FromMinutes(5));
                //var redisdb = RedisClient.redisClient.GetStringKey<List<internal_product>>("OyxKey");
                //apiResult.totalCount = redisdb.Count();
                //apiResult.pageCount = (int)Math.Ceiling(redisdb.Count() * 1.0 / pageSize);
                //apiResult.Data = redisdb.OrderByDescending(x => x._add_time).ToList();
                var list = await _i_Internal_Product_Repository.GetShowInforAsync(pageSize, pageIndex, whereexp);
                apiResult.totalCount = list.TotalCount;
                apiResult.pageCount = list.PageCount;
                apiResult.Data = list.Data.OrderByDescending(x => x._add_time).ToList();
                RedisClient.redisClient.SetStringKey("OyxKey", apiResult, TimeSpan.FromMinutes(5));
                return apiResult;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 添加-内部生产
        /// </summary>
        /// <param name="product_DTO">内部生产DTO</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiResult> Post_Add_internal_product(internal_product_DTO product_DTO)
        {
            ApiResult apiResult = new ApiResult();
            if (product_DTO == null)
            {
                apiResult.Code = 500;
                apiResult.Message = "添加不能为空";
                return apiResult;
            }
            try
            {
                //开启事务
                _i_Internal_Product_Repository.BeginTranInfor();
                var res3 = cross_Service_Helper.Get("http://10.31.59.5:8002/api/Approval_form/GetShowSystem").Result;
                var geinfor = JsonConvert.DeserializeObject<List<proce_DTO>>(res3);
                //判断审批状态是否开启
                var xiaos = geinfor.Where(c => c.approval_name == "销售系统").FirstOrDefault();
                var Internal_Product = _mapper.Map<internal_product>(product_DTO);
                //添加内部生产
                Internal_Product._add_name = product_DTO._add_name;
                Internal_Product._add_time = DateTime.Now;
                //DTO转换
                var produce_product = _mapper.Map<List<produce_product>>(product_DTO.produce_Product_DTOs);
                var produce_material = _mapper.Map<List<produce_material>>(product_DTO.produce_Material_DTOs);
                //批量添加内部生产产品关系表
                foreach (var item in produce_product)
                {
                    item.internal_product_id = product_DTO.internal_product_id;
                }
                foreach (var item in produce_material)
                {
                    item.internal_product_id = product_DTO.internal_product_id;
                }
                if (xiaos.approval_on_no)
                {
                    //如果为开启状态存入Redis中
                    RedisClient.redisClient.HsetInforAsync("inteList", Internal_Product.internal_product_id, Internal_Product);
                    RedisClient.redisClient.HsetInforAsync("proList", Internal_Product.internal_product_id, produce_product);
                    RedisClient.redisClient.HsetInforAsync("mateList", Internal_Product.internal_product_id, produce_material);
                    var res = await _i_Internal_Product_Repository.AddInfor_Async(Internal_Product);
                    //批量添加内部生产物料关系表
                    var res1 = _Produce_Product_Repository.AddInfor_Batch(produce_product);
                    var res2 = _produce_material_Repository.AddInfor_Batch(produce_material);
                    string numberName = "生产系统-" + product_DTO.internal_product_id;
                    capPublisher.Publish("GetNewNumber", numberName);
                    apiResult.Code = 300;
                    apiResult.Message = "等待审批，审批后自动执行";
                    return apiResult;
                }
                else
                {
                    apiResult.Code = 200;
                    apiResult.Message = "添加成功";
                    //添加成功需要传一个消息队列  传递哪个模块 还有编号
                    string numberName = "生产系统-" + product_DTO.internal_product_id;
                    capPublisher.Publish("GetNewNumber", numberName);
                    _Produce_Product_Repository.CommitTranInfor();
                    return apiResult;
                }
            }
            catch (Exception)
            {
                _i_Internal_Product_Repository.RollbackTranInfor();
                throw;
            }
        }
        public async Task<ApiReturn<string>> GetAddXsInfor(string? id)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var rew = await RedisClient.redisClient.HgetInforAsync<internal_product>("inteList", id);
            var res1 = await RedisClient.redisClient.HgetInforAsync<List<produce_product>>("proList", id);
            var res2 = await RedisClient.redisClient.HgetInforAsync<List<produce_material>>("mateList", id);
            var res = await _i_Internal_Product_Repository.AddInfor_Async(rew);
            var rese = await _Produce_Product_Repository.AddInfor_Batch_Async(res1);
            var res3 = await _produce_material_Repository.AddInfor_Batch_Async(res2);
            if (res > 0&& rese > 0&& res3 > 0)
            {
                apiReturn.Code = 200;
                apiReturn.Message = "添加成功";
            }
            return apiReturn;

        }
        /// <summary>
        /// 批量删除-内部生产
        /// </summary>
        /// <param name="product_DTO">内部生产DTO</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiResult> Post_Batch_Del_internal_produc(List<internal_product_DTO> product_DTO)
        {
            ApiResult apiResult = new ApiResult();

            try
            {
                //开启事务
                _i_Internal_Product_Repository.BeginTranInfor();
                //DTO集合转换内部生产集合
                var internal_product = _mapper.Map<List<internal_product>>(product_DTO);
                //批量删除内部生产
                var res = await _i_Internal_Product_Repository.DelInfor_Batch_Async(internal_product);
                foreach (var item in product_DTO)
                {
                    //查询内部生产产品关系
                    var produce_product = _Produce_Product_Repository.GetShowInfor().Where(x => x.internal_product_id == item.internal_product_id).ToList();
                    //删除内部生产产品关系表
                    var res1 = await _Produce_Product_Repository.DelInfor_Batch_Async(produce_product);
                    //查询产品物料关系表
                    var produce_material = _produce_material_Repository.GetShowInfor().Where(x => x.internal_product_id == item.internal_product_id).ToList();
                    var res2 = await _produce_material_Repository.DelInfor_Batch_Async(produce_material);
                }
                if (res > 0)
                {
                    apiResult.Code = 200;
                    apiResult.Message = "删除成功";
                    _i_Internal_Product_Repository.CommitTranInfor();
                }
                else
                {
                    apiResult.Code = 500;
                    apiResult.Message = "删除失败";
                    _i_Internal_Product_Repository.RollbackTranInfor();
                }

                return apiResult;
            }
            catch (Exception)
            {
                _i_Internal_Product_Repository.RollbackTranInfor();
                throw;
            }

        }



        /// <summary>
        /// 修改-内部生产
        /// </summary>
        /// <param name="product_DTO">内部生产DTO</param>
        /// <returns>统一返回格式</returns>
        public ApiResult Post_Upd_internal_produc(internal_product_DTO product_DTO)
        {
            ApiResult apiResult = new ApiResult();

            try
            {
                _i_Internal_Product_Repository.BeginTranInfor();
                //修改内部生产
                var internal_product = _mapper.Map<internal_product>(product_DTO);
                var res = _i_Internal_Product_Repository.UpdInfor(internal_product);
                //删除之前的产品关系
                var produce_product = _mapper.Map<List<produce_product>>(product_DTO.produce_Product_DTOs).Where(x => x.internal_product_id == internal_product.internal_product_id).ToList();
                var res1 = _Produce_Product_Repository.DelInfor_Batch(produce_product);
                //删除之前的物料关系
                var produce_material = _mapper.Map<List<produce_material>>(product_DTO.produce_Material_DTOs).Where(x => x.internal_product_id == internal_product.internal_product_id).ToList();
                var res2 = _produce_material_Repository.DelInfor_Batch(produce_material);
                //批量添加修改后的产品关系表和批量添加修改后的物料关系表
                var produce_product_1 = _mapper.Map<List<produce_product>>(product_DTO.produce_Product_DTOs);
                foreach (var item in produce_product_1)
                {
                    item.internal_product_id = internal_product.internal_product_id;
                }
                var produce_material_1 = _mapper.Map<List<produce_material>>(product_DTO.produce_Material_DTOs);
                foreach (var item in produce_material_1)
                {
                    item.internal_product_id = internal_product.internal_product_id;
                }
                var res3 = _Produce_Product_Repository.AddInfor_Batch(produce_product_1);
                var res4 = _produce_material_Repository.AddInfor_Batch(produce_material_1);
                if (res > 0)
                {
                    if (res3 > 0)
                    {
                        if (res4 > 0)
                        {
                            apiResult.Code = 200;
                            apiResult.Message = "修改成功";
                            _i_Internal_Product_Repository.CommitTranInfor();
                        }
                    }
                }
                else
                {
                    apiResult.Code = 500;
                    apiResult.Message = "修改失败";
                    _i_Internal_Product_Repository.RollbackTranInfor();
                }
                return apiResult;
            }
            catch (Exception)
            {
                _i_Internal_Product_Repository.RollbackTranInfor();
                throw;
            }

        }
        /// <summary>
        /// 返回内部生产实体
        /// </summary>
        /// <param name="internal_product_id">内部生产编号</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiResult> Get_ReturmModel_internal_product(string? internal_product_id)
        {
            ApiResult apiResult = new ApiResult();
            try
            {
                var res = await _i_Internal_Product_Repository.GetShowObjAsync(x => x.internal_product_id == internal_product_id);
                var dto = _mapper.Map<internal_product_DTO>(res);
                var produce_Product = _Produce_Product_Repository.GetShowInfor(x => x.internal_product_id == internal_product_id);
                dto.produce_Product_DTOs = _mapper.Map<List<produce_product_DTO>>(produce_Product);
                var produce_Material = _produce_material_Repository.GetShowInfor(x => x.internal_product_id == internal_product_id);
                dto.produce_Material_DTOs = _mapper.Map<List<produce_material_DTO>>(produce_Material);
                if (res != null)
                {
                    apiResult.Code = 200;
                    apiResult.Message = "返回成功";
                    apiResult.Data = dto;
                }
                else
                {
                    apiResult.Code = 500;
                    apiResult.Message = "返回失败";
                }
            }
            catch (Exception)
            {

                throw;
            }
            return apiResult;
        }
        /// <summary>
        /// 获取生产BOM
        /// </summary>
        /// <param name="Url">路径</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="pageIndex">页码</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiResult> Get_Produce_Bom(string? Url, int pageSize, int pageIndex)
        {
            try
            {
                var Url2 = "http://10.31.59.21:8087/api/Bom_management_table/GetBOMrelations";
                var produce = await _cross_service_helper.Get(Url);
                var produce_List = JsonConvert.DeserializeObject<PageETO<sales_product>>(produce);
                var Bom = await _cross_service_helper.Get(Url2);
                var Bom_List = JsonConvert.DeserializeObject<List<Product_BOMDTO>>(Bom);
                var list = (from a in produce_List.Data
                            join b in Bom_List on a.productid equals b.finished_number
                            where a.productid == b.finished_number
                            select new
                            {
                                a.sales_number,
                                a.price,
                                a.productid,
                                a.productname,
                                a.specifications_and_models,
                                a.unit,
                                a.quantity,
                                a.date_released,
                                b.bom_number,
                                b.daily_output,
                            }).AsQueryable();
                ApiResult apiResult = new ApiResult();
                apiResult.totalCount = list.Count();
                apiResult.pageCount = (int)Math.Ceiling(list.Count() * 1.0 / pageSize);
                list = list.Skip((pageIndex - 1) * pageSize).Take(pageSize);
                apiResult.Data = list.ToList();
                return apiResult;
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}
